package com.yeyv.net.Web.Service.Implement;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yeyv.net.UsefulEntity.Constant;
import com.yeyv.net.Web.Entity.GameCdkEntity;
import com.yeyv.net.Web.Mapper.GameCdkMapper;
import com.yeyv.net.Web.Service.GameCdkService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

@DS("master")
@Service
public class GameCdkImpl extends ServiceImpl<GameCdkMapper, GameCdkEntity> implements GameCdkService {
    @Autowired
    private GameCdkMapper gameCdkMapper;

    /**
     * 验证CDKey是否有效
     *
     * @param game
     * @param cdk
     * @return
     */
    @DS("master")
    @Override
    public boolean validateCdk(String game, String cdk) {
        var result = this.getOne(new LambdaQueryWrapper<GameCdkEntity>()
                .eq(GameCdkEntity::getCdk, cdk)
                .eq(GameCdkEntity::getGame, game)
                .eq(GameCdkEntity::getStatus, 1)
                .isNull(GameCdkEntity::getUsername)
        );
        return result != null;
    }

    /**
     * 使用CDKey 不绑定用户
     *
     * @param game
     * @param cdk
     * @return
     */
    @DS("master")
    @Override
    public boolean useCdk(String game, String cdk) {
        if (!this.validateCdk(game, cdk)) {
            return false;
        }
        var result = this.getOne(new LambdaQueryWrapper<GameCdkEntity>()
                .eq(GameCdkEntity::getCdk, cdk)
                .eq(GameCdkEntity::getGame, game)
                .eq(GameCdkEntity::getStatus, 1)
        );
        result.setStatus(2);
        result.setUseTime(new Date());
        this.updateById(result);
        return true;
    }

    /**
     * 验证{username}是否已经有CDKey了
     *
     * @param game
     * @param username
     * @return
     */
    @Override
    public boolean validateUserBind(String game, String username) {
        var result = this.getOne(new LambdaQueryWrapper<GameCdkEntity>()
                .eq(GameCdkEntity::getGame, game)
                .eq(GameCdkEntity::getStatus, 2)
                .eq(GameCdkEntity::getUsername, username)
        );
        return result != null;
    }

    /**
     * 绑定CDKey 绑定user
     *
     * @param game
     * @param cdk
     * @param username
     * @return
     */
    @Override
    public boolean bindCdk(String game, String cdk, String username) {
        if (!this.validateCdk(game, cdk)) {
            return false;
        }
        //如果已经绑定过了 直接返回
        if (validateUserBind(game, username)) {
            return false;
        }
        var result = this.getOne(new LambdaQueryWrapper<GameCdkEntity>()
                .eq(GameCdkEntity::getCdk, cdk)
                .eq(GameCdkEntity::getGame, game)
                .eq(GameCdkEntity::getStatus, 1)
        );
        result.setStatus(2);
        result.setUsername(username);
        result.setUseTime(new Date());
        this.updateById(result);
        return true;
    }

    @DS("master")
    @Override
    public String spawnCdk(String game) {
        StringBuilder cdk = new StringBuilder();
        while (true) {
            cdk.append(Constant.random(4)).append("-")
                    .append(Constant.random(4)).append("-")
                    .append(Constant.random(4)).append("-")
                    .append(Constant.random(4)).append("-")
                    .append(Constant.random(4))
            ;
            var result = this.count(new LambdaQueryWrapper<GameCdkEntity>()
                    .eq(GameCdkEntity::getCdk, cdk.toString())
                    .eq(GameCdkEntity::getGame, game)
            );
            if (result != 0) {
                continue;
            }
            var entity = new GameCdkEntity();
            entity.setType(1);
            entity.setCreateTime(new Date());
            entity.setStatus(1);
            entity.setCdk(cdk.toString());
            entity.setGame(game);
            this.save(entity);
            break;
        }
        return cdk.toString();
    }
}
